<template>
  <div :class="{'xdh-form--inline': inline,'xdh-form--columns':columnNumber>1}">
    <template v-for="(item, index) in data">
      <!-- 不需提交表单类别，不需有key -->
      <!-- 标题 -->
      <xdh-title v-if="isEqual(item, 'title')"
                 v-bind="item.props||{}"></xdh-title>

      <!-- 需提交表单类别，需带上key -->
      <!-- input 输入框-->
      <el-form-item v-if="isEqual(item, 'input')"
                    :key="`${item.name}_${index}`"
                    :label="item.label"
                    :prop="getProp(item)"
                    :style="setStyle(item.columnNumber)"
                    :rules="item.rules">
        <el-input v-if="!view"
                  v-bind="item.props || {}"
                  v-model="model[item.name]"></el-input>
        <div v-else>{{model[item.name] || '-'}}</div>
      </el-form-item>

      <!-- radio 单选-->
      <el-form-item v-if="isEqual(item, 'radio')"
                    :key="`${item.name}_${index}`"
                    :label="item.label"
                    :prop="getProp(item)"
                    :style="setStyle(item.columnNumber)"
                    :rules="item.rules">
        <el-radio-group v-if="!view"
                        v-bind="item.props || {}"
                        v-model="model[item.name]">
          <el-radio v-for="option in item.options || []"
                    :key="option.name"
                    :label="option.name">
            {{option.label}}
          </el-radio>
        </el-radio-group>
        <div v-else v-html="getViewValue(item.options,model[item.name])"></div>
      </el-form-item>

      <!-- checkbox 复选-->
      <el-form-item v-if="isEqual(item, 'checkbox')"
                    :key="`${item.name}_${index}`"
                    :label="item.label"
                    :prop="getProp(item)"
                    :style="setStyle(item.columnNumber)"
                    :rules="item.rules">
        <el-checkbox-group v-if="!view"
                           v-bind="item.props || {}"
                           v-model="model[item.name]">
          <el-checkbox v-for="option in item.options || []"
                       :key="option.name"
                       :label="option.name">{{option.label}}
          </el-checkbox>
        </el-checkbox-group>
        <div v-else v-html="getViewValue(item.options,model[item.name])"></div>
      </el-form-item>

      <!-- select 下拉框-->
      <el-form-item v-if="isEqual(item, 'select')"
                    :key="`${item.name}_${index}`"
                    :label="item.label"
                    :prop="getProp(item)"
                    :rules="item.rules"
                    :style="setStyle(item.columnNumber)">
        <el-select v-if="!view"
                   clearable
                   filterable
                   :disabled="view"
                   v-bind="item.props || {}"
                   v-model="model[item.name]">
          <el-option v-for="option in item.options || []"
                     :key="option.name"
                     :value="option.name"
                     :label="option.label"></el-option>
        </el-select>
        <div v-else v-html="getViewValue(item.options,model[item.name])"></div>
      </el-form-item>

      <!-- datePicker 时间控件-->
      <el-form-item v-if="isEqual(item, 'datePicker')"
                    :key="`${item.name}_${index}`"
                    :label="item.label"
                    :prop="getProp(item)"
                    :style="setStyle(item.columnNumber)"
                    :rules="item.rules">
        <el-date-picker v-if="!view"
                        v-bind="item.props || {}"
                        v-model="model[item.name]"></el-date-picker>
        <div v-else>{{model[item.name] || '-'}}</div>
      </el-form-item>

      <!-- treeSelect 下拉树-->
      <el-form-item v-if="isEqual(item, 'treeSelect')"
                    :key="`${item.name}_${index}`"
                    :label="item.label"
                    :prop="getProp(item)"
                    :style="setStyle(item.columnNumber)"
                    :rules="item.rules">
        <xdh-tree-select v-if="!view"
                         v-bind="item.props || {}"
                         v-model="model[item.name]"
                         :data="item.options"
                         :show-clear-btn="false"
                         node-key="id"
                         :on-selected="handleSelectTree(item)"></xdh-tree-select>
        <div v-else v-html="getViewTreeValue(item.options,model[item.name])"></div>
      </el-form-item>

      <!-- upload 批量上传数据-->
      <el-form-item v-if="isEqual(item, 'upload')"
                    :key="`${item.name}_${index}`"
                    :label="item.label"
                    :prop="getProp(item)"
                    :style="setStyle(item.columnNumber)"
                    :rules="item.rules">
        <el-upload v-show="!view"
                   v-bind="item.props || {}"
                   multiple
                   :showFileList="false"
                   :on-success="handleUploadSuccess(item)"
                   :on-exceed="handleExceed(item)"
                   :before-remove="handleUploadBeforeRemove"
                   :on-remove="handleUploadRemove(item)">
          <slot name="upload" :item="item">
            <el-button type="primary" size="mini">点击选择文件</el-button>
          </slot>
        </el-upload>

        <!--上传之后显示下载内容-->
        <xdh-form-attachments :list="model[item.name]" v-show="model[item.name].length>0"></xdh-form-attachments>
      </el-form-item>

      <!--批量导入数据-->
      <el-form-item v-if="isEqual(item, 'import')"
                    :key="`${item.name}_${index}`"
                    :label="item.label"
                    :prop="getProp(item)"
                    :rules="item.rules"
                    :style="setStyle(item.columnNumber)">
        <xdh-form-import ref="importList" :view="view" :uploadProps="uploadProps" @on-select="handleImportSelect($event,item)" :item="item" :load="getImportData(model[item.name])"></xdh-form-import>
      </el-form-item>

      <!-- custom -->
      <el-form-item v-if="isEqual(item, 'custom')"
                    :key="`${item.name}_${index}`">
        <slot name="custom" :item="item" :index="index"></slot>
      </el-form-item>

      <!-- 遍历分支 -->
      <xdh-form-items v-for="(items, name) in item.branches || {}"
                      v-if="isMatchBranch(item, name)"
                      :columnNumber="item.columnNumber"
                      :key="name"
                      :data="items"
                      :model="model"
                      :view="view">
      </xdh-form-items>

      <!-- 遍历子表单 -->
      <xdh-form-items v-for="(columns, rowIndex) in item.children || []"
                      class="xdh-form-row"
                      :key="`${item.name}_${rowIndex}`"
                      :inline="item.inline"
                      :data="columns"
                      :root-name="item.name"
                      :rowIndex="rowIndex"
                      :model="model[item.name][rowIndex]"
                      :view="view">
        <div class="xdh-form-append" v-if="!view">
          <slot name="row-append" :parent-index="index" :columns="columns" :index="rowIndex"></slot>
        </div>
      </xdh-form-items>

    </template>
    <slot></slot>
  </div>
</template>

<script>
  import Vue from 'vue'
  import XdhTitle from '@/widgets/xdh-title'
  import XdhTreeSelect from '@/widgets/xdh-tree-select'
  import XdhListPanel from '@/widgets/xdh-list-panel'
  import XdhFormAttachments from './components/xdh-form-attachments.vue'
  import XdhFormImport from './components/xdh-form-import.vue'

  export default {
    name: 'XdhFormItems',
    components: {
      XdhTitle,
      XdhTreeSelect,
      XdhListPanel,
      XdhFormAttachments,
      XdhFormImport
    },
    props: {
      mixin: {
        type: Object
      },
      uploadProps: {
        type: Object
      },
      view: {
        type: Boolean,
        default: false
      },
      //  [{label, name, type, props, options, value, rules, children, branches}]
      data: {
        type: Array
      },
      // 数据模型
      model: {
        type: Object,
        default() {
          return Object.create(null)
        }
      },
      // 根字段名称
      rootName: {
        type: String
      },
      // 当前children的行索引
      rowIndex: {
        type: Number
      },
      // 是否inline显示
      inline: {
        type: Boolean,
        default: true
      },
      // 是否多列显示
      columnNumber: {
        type: [String, Number],
        default: 1
      }
    },
    watch: {
      uploadProps(data) {
      }
    },
    data() {
      return {
        vm: null
      }
    },
    methods: {
      /**
       * 判断是否为指定类型的表单项
       * @param item
       * @param value
       * @returns {boolean}
       */
      isEqual(item = {}, value) {
        if (item.children) {
          return false
        } else {
          const type = item.type
          return type && type.toLowerCase() === value.toLowerCase()
        }
      },
      /**
       * 是否有级联下拉分支
       * @param item
       * @param name
       * @returns {boolean}
       */
      isMatchBranch(item = {}, name) {
        const value = this.model[item.name]
        return Array.isArray(value) ? value.includes(name) : value === name
      },
      /**
       * 获取自定义配置的表单项props
       * @param item
       * @returns {string}
       */
      getProp(item) {
        if (this.rootName) {
          return `${this.rootName}.${this.rowIndex}.${item.name}`
        } else {
          return item.name
        }
      },
      /**
       * 设置每行显示多少列表单项
       * @param columnNumber
       * @returns {{width: string}}
       */
      setStyle(columnNumber) {
        let obj = {width: parseInt(100 / columnNumber) - 0.5 + '%'}
        if (columnNumber > 1) {
          obj.display = 'inline-block'
        }
        return obj
      },
      /**
       * 回填数据对应的值
       */
      getViewValue(options = [], value, key = 'name') {
        let data = []
        if (Array.isArray(value)) {
          value.forEach(v => {
            options.map(n => {
              if (n[key] === v) {
                data.push(n.label)
                return false;
              }
            })
          })
        } else {
          data = options.map(n => {
            if (n[key] === value) {
              return n.label
            }
          })
        }
        return data.join('') || '-'
      },
      getViewTreeValue(options = [], value) {
        let arr = []
        const parser = function (data, v) {
          data.map(n => {
            if (n.id === v) {
              arr.push(n.label)
              return false;
            }
            if (n.children && n.children.length > 0) {
              parser(n.children, v)
            }
          })
        }

        value.forEach(v => {
          parser(options, v)
        })
        return arr.join('，') || '-'
      },
      /**
       * 上传控件
       */
      handleUploadBeforeRemove(file) {
        return this.$confirm(`确定移除 ${file.name} ?`)
      },
      handleUploadSuccess(item) {
        const handler = function (res, file, fileList) {
          this.model[item.name] = fileList
        }
        return handler.bind(this)
      },
      handleUploadRemove(item) {
        const handler = function (file, fileList) {
          this.model[item.name] = fileList
        }
        return handler.bind(this)
      },
      handleExceed(item) {
        const handler = function (files, fileList) {
          this.$message.warning(`当前限制选择 ${item.limit} 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`);
        }
        return handler.bind(this)
      },

      /**
       * 选择下拉树的回调操作
       * @param item
       * @returns {function(this:methods)}
       */
      handleSelectTree(item) {
        const handler = function (nodes) {
          this.model[item.name] = nodes
        }
        return handler.bind(this)
      },

      /**
       * 选择批量导入的数据
       * @param obj
       * @param item
       */
      handleImportSelect(obj, item) {
        this.model[item.name] = obj.excelId
      },
      /**
       * 读取批量导入的数据
       */
      getImportData(excelId) {
        const handler = function () {
          return this.vm.getSelectedExcel({name: 'bdaj', excelId: excelId, limit: 1000, page: 1}).then(res => {
            return res
          }).catch(err => {
            return Promise.reject(err)
          })
        }
        return handler.bind(this)
      }
    },
    created() {
      if (this.mixin) {
        this.vm = new Vue(this.mixin)
      }
    },
    mounted() {
    }
  }
</script>
